<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr">
    <head>
        <title></title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />        
        <link rel="stylesheet" type="text/css" href="../../css/guide.css" />        
        <script type="text/javascript">var basepath = '../../'; var lang = 'fr';</script>        
        <script type="text/javascript" src="../../js/loader.js"></script>        
    </head>
    <body>     
        <h1>Créer un formulaire</h1>
        <p>
            Dans ce tutoriel nous allons créer un simple formulaire de contact qui envoi un mail et que vous pourrez 
            utiliser dans vos applications. <a href="#captcha">Voir le résultat final</a>
        </p>
        <blockquote class="warning">
            Ce tutoriel est prévu pour fonctionner avec une nouvelle installation de PHP-Oxygen.
        </blockquote>
        
        <h2>Module form</h2>
        <p>
            Dans le dossier <a href="../general/structure.html#module">module</a>, créez les dossiers suivants :
        </p>
        <ul>
            <li>form
                <ul>
                    <li>action</li>
                    <li>template</li>
                </ul>
            </li>            
        </ul>
        
        <h2>Affichage du formulaire</h2>
        <p>
            Pour commencer nous allons créer le gabarit HTML de notre formulaire dans le dossier template de notre 
            module. Nous allons l'appeler form.html
        </p>
        
        <sub>module/form/template/form.html</sub>
        <pre class='brush: xml'>
            &lt;form action="" method="post">
                &lt;p>
                    &lt;label for="name">Votre nom&lt;/label>&lt;br />
                    &lt;input type="text" value="" name="contact[name]" id="name" />
                &lt;/p>    
                &lt;p>
                    &lt;label for="email">Votre e-mail&lt;/label>&lt;br />
                    &lt;input type="text" value="" name="contact[email]" id="email" />
                &lt;/p>    
                &lt;p>
                    &lt;label for="subject">Sujet du message&lt;/label>&lt;br />
                    &lt;input type="text" value="" name="contact[subject]" id="subject" />
                &lt;/p>    
                &lt;p>
                    &lt;label for="message">Votre message&lt;/label>&lt;br />
                    &lt;textarea name="contact[message]" id="message">&lt;/textarea>
                &lt;/p>    
                &lt;p>
                    &lt;button type="submit">Soumettre&lt;/button>
                &lt;/p>
            &lt;/form>
        </pre>
        
        <p>
            Puis nous allons créer le contrôleur (action) qui va gérer la soumission du formulaire ainsi que son affichage.
        </p>
        <p>
            Pour cela on va créer le fichier <code>index.class.php</code> dans le dossier <code>action</code> du 
            module.
        </p>
        
        <sub>module/form/action/index.class.php</sub>
        <pre class='brush: php'>
        &lt;?php
        class m_form_action_Index extends Action
        {
            public function execute()
            {
                // on affiche le gabarit form.html
                $this->setView('form.html');
            }
        }
        </pre>
        
        <p>
            Vous devriez pouvoir visualiser le formulaire en saisissant /form à la 
            fin de votre url. Exemple : http://localhost/form
        </p>
        
        <h2>Récupération des données postées</h2>
        <p>            
            La récupération des données postées se fera dans notre contrôleur avec la  
            <a href="../classes/form.html#getvalues">méthode getValues()</a> de la classe 
            <a href="../classes/form.html">Form</a>. La classe <a href="../classes/form.html">Form</a> ne
            s'instancie que lorsque des données sont postées.
        </p>
        
        <sub>module/form/action/index.class.php</sub>
        <pre class='brush: php'>
        &lt;?php
        class m_form_action_Index extends Action
        {
            public function execute()
            {
                // on instancie la classe si des données sont postées
                if($form = Form::getInstance('contact'))
                {
                    // affichage des valeurs
                    print_r($form->getValues(true));
                    /*
                        (exemple)
                        Array
                        (
                            [name] => Sébastien
                            [email] => mail@example.tld
                            [subject] => test
                            [message] => Message de test
                        )
                    */
                }

                // on affiche le gabarit form.html
                $this->setView('form.html');
            }
        }
        </pre>
        <blockquote class="info">
            Nous donnons "contact" en argument du getInstance de la classe Form car nous avons nommé les champs de notre 
            formulaire avec un tableau associatif contact (contact[name], contact[email], contact[subject], 
            contact[message])            
        </blockquote>
        
        <h2>Vérification des données</h2>
        <p>
            Toujours dans notre contrôleur, nous allons vérifier les données soumises à l'aide de la 
            <a href="../classes/form.html#check">méthode check()</a> de la classe <a href="../classes/form.html">Form</a>.
        </p>
        <sub>module/form/action/index.class.php</sub>
        <pre class='brush: php'>
        &lt;?php
        class m_form_action_Index extends Action
        {
            public function execute()
            {
                // on instancie la classe si des données sont postées
                if($form = Form::getInstance('contact'))
                {
                    // on défini les règles de vérification par champ
                    $form->check('name',    'required|length[3]');
                    $form->check('email',   'required|email');
                    $form->check('subject', 'required|length[3]');
                    $form->check('message', 'required');    

                    // les données sont valides
                    if($form->isValid())
                    {
                        // affichage des valeurs
                        print_r($form->getValues(true));
                    }
                }

                // on affiche le gabarit form.html
                $this->setView('form.html');
            }
        }
        </pre>
        
        <h2>Affichage des erreurs / Renvoi des valeurs à la vue</h2>
        <p>
            Il est temps d'informer l'internaute des erreurs qu'il a pu commettre. Pour cela on va les fournir à la vue 
            (à form.html) en utilisant la <a href="../classes/form.html#geterrors">méthode getErrors()</a> de la classe 
            <a href="../classes/form.html">Form</a>.
        </p>
        <p>
            Nous allons également en profiter pour renvoyer les valeurs saisie par l'internaute à la vue pour éviter à 
            ce dernier de se retrouver avec un formulaire vide à chaque fois qu'il fait un erreur. Pour cela nous 
            utilisons la <a href="../classes/form.html#getvalues">méthode getValues()</a> de la classe 
            <a href="../classes/form.html">Form</a>.
        </p>
        <sub>module/form/action/index.class.php</sub>
        <pre class='brush: php'>
        &lt;?php
        class m_form_action_Index extends Action
        {
            public function execute()
            {
                // on instancie la classe si des données sont postées
                if($form = Form::getInstance('contact'))
                {
                    // on défini les règles de vérification par champ
                    $form->check('name',    'required|length[3]');
                    $form->check('email',   'required|email');
                    $form->check('subject', 'required|length[3]');
                    $form->check('message', 'required');    

                    // les données sont valides
                    if($form->isValid())
                    {
                        // affichage des valeurs
                        print_r($form->getValues(true));
                    }
                    else
                    {
                        // on fourni les erreurs à la vue
                        $this->setModel('errors', $form->getErrors());

                        // puis les valeurs
                        $this->setModel('values', $form->getValues(true));
                    }
                }

                // on affiche le gabarit form.html
                $this->setView('form.html');
            }
        }
        </pre>
        
        <p>
            On va alors modifier le gabarit pour afficher les erreurs et renvoyer les valeurs soumises champ par champ.
        </p>
        <sub>module/form/template/form.html</sub>
        <pre class="brush: xml">
            &lt;form action="" method="post">
                &lt;p>
                    &lt;label for="name">Votre nom&lt;/label>&lt;br />
                    &lt;input type="text" name="contact[name]" id="name" value="{$values.name}" />
                    {if isset($errors.name)}&lt;span style="color:red">{$errors.name}&lt;/span>{/if}
                &lt;/p>  
                &lt;p>
                    &lt;label for="email">Votre e-mail&lt;/label>&lt;br />
                    &lt;input type="text" name="contact[email]" id="email" value="{$values.email}" />
                    {if isset($errors.email)}&lt;span style="color:red">{$errors.email}&lt;/span>{/if}
                &lt;/p>       
                &lt;p>
                    &lt;label for="subject">Sujet du message&lt;/label>&lt;br />
                    &lt;input type="text" name="contact[subject]" id="subject" value="{$values.subject}" />
                    {if isset($errors.subject)}&lt;span style="color:red">{$errors.subject}&lt;/span>{/if}
                &lt;/p>   
                &lt;p>
                    &lt;label for="message">Votre message&lt;/label>&lt;br />
                    &lt;textarea name="contact[message]" id="message">{$values.message}&lt;/textarea>
                    {if isset($errors.message)}&lt;span style="color:red">{$errors.message}&lt;/span>{/if}
                &lt;/p>   
                &lt;p>
                    &lt;button type="submit">Soumettre&lt;/button>
                &lt;/p>
            &lt;/form>
        </pre>
        <blockquote class="info">
            Vous pouvez également afficher toutes les erreurs dans un seul élément div par exemple en utilisant la balise 
            {foreach} de Smarty.
        </blockquote>
        
        <h2>Traitement des données / Message de succès</h2>
        <p>
            Pour finir on va envoyer l'email à l'aide de la classe <a href="../classes/email.html">Email</a> et on va
            afficher un message de succes.
        </p>
        
        <sub>module/form/action/index.class.php</sub>
        <pre class='brush: php'>
        &lt;?php
        class m_form_action_Index extends Action
        {
            public function execute()
            {
                // on instancie la classe si des données sont postées
                if($form = Form::getInstance('contact'))
                {
                    // on défini les règles de vérification par champ
                    $form->check('name',    'required|length[3]');
                    $form->check('email',   'required|email');
                    $form->check('subject', 'required|length[3]');
                    $form->check('message', 'required');    

                    // on récupère les valeurs dans un tableau associatif
                    $values = $form->getValues(true);

                    // les données sont valides
                    if($form->isValid())
                    {
                        // on envoi le mail
                        Email::to('me@example.org')->from($values['email'], $values['nom'])
                                                   ->subject($values['subject'])
                                                   ->bodyText($values['message'])
                                                   ->send();
                        
                        // on dit à la vue d'afficher le message de succès
                        $this->setModel('success', true);

                        // on réinitialise les valeurs
                        $this->setModel('values', array());
                    }
                    else
                    {
                        // on fourni les erreurs à la vue
                        $this->setModel('errors', $form->getErrors());

                        // puis les valeurs
                        $this->setModel('values', $values);
                    }
                }

                // on affiche le gabarit form.html
                $this->setView('form.html');
            }
        }
        </pre>
        <p>
            On ajoute cette ligne au début du gabarit
        </p>
        <sub>module/form/template/form.html</sub>
        <pre class="brush: xml">
            {if isset($success)}<p>Merci ! Nous vous répondrons dans les meilleurs délais</p>{/if}
        </pre>
        
        <a name="captcha"></a>
        <h2>Captcha</h2>
        <p>
            Dernière étape, on va protéger notre formulaire en utilisant un captcha invisible. Pour cela on va utiliser 
            les méthodes <a href="../classes/form.html#getcaptchatags">getCaptchaTags()</a> et 
            <a href="../classes/form.html#checkcaptcha">checkCaptcha()</a> de la classe 
            <a href="../classes/form.html">Form</a>
        </p>
        <sub>module/form/action/index.class.php</sub>
        <pre class='brush: php'>
        &lt;?php
        class m_form_action_Index extends Action
        {
            public function execute()
            {
                // on instancie la classe si des données sont postées
                if($form = Form::getInstance('contact'))
                {
                    // on défini les règles de vérification par champ
                    $form->check('name',    'required|length[3]');
                    $form->check('email',   'required|email');
                    $form->check('subject', 'required|length[3]');
                    $form->check('message', 'required');    

                    // on ajoute la vérification du captcha
                    $form->checkCaptcha();

                    // on récupère les valeurs dans un tableau associatif
                    $values = $form->getValues(true);

                    // les données sont valides
                    if($form->isValid())
                    {
                        // on envoi le mail
                        Email::to('me@example.org')->from($values['email'], $values['nom'])
                                                   ->subject($values['subject'])
                                                   ->bodyText($values['message'])
                                                   ->send();

                        // on dit à la vue d'afficher le message de succès
                        $this->setModel('success', true);

                        // on réinitialise les valeurs
                        $this->setModel('values', array());
                    }
                    else
                    {
                        // on fourni les erreurs à la vue
                        $this->setModel('errors', $form->getErrors());

                        // puis les valeurs
                        $this->setModel('values', $values);
                    }
                }

                // on envoi le captcha pour affichage
                $this->setModel('captcha', Form::getCaptchaTags());

                // on affiche le gabarit form.html
                $this->setView('form.html');
            }
        }
        </pre>
        <p>
            Puis on modifie le gabarit pour afficher l'erreur du captcha et le numéro d'erreur retourné. Voir 
            <a href="../classes/form.html#checkcaptcha">checkCaptcha()</a> de la classe 
            <a href="../classes/form.html">Form</a>
        </p>
        <sub>module/form/template/form.html</sub>
        <pre class="brush: xml">
            {if isset($success)}<p>Merci ! Nous vous répondrons dans les meilleurs délais.</p>{/if}
            <form action="" method="post">
                {$captcha}
                {if isset($errors.captcha)}<p style="color:red">Erreur captcha numéro {$errors.captcha}</p>{/if}
                <p>
                    <label for="name">Votre nom</label><br />
                    <input type="text" name="contact[name]" id="name" value="{$values.name}" />
                    {if isset($errors.name)}<span style="color:red">{$errors.name}</span>{/if}
                </p>  
                <p>
                    <label for="email">Votre e-mail</label><br />
                    <input type="text" name="contact[email]" id="email" value="{$values.email}" />
                    {if isset($errors.email)}<span style="color:red">{$errors.email}</span>{/if}
                </p>       
                <p>
                    <label for="subject">Sujet du message</label><br />
                    <input type="text" name="contact[subject]" id="subject" value="{$values.subject}" />
                    {if isset($errors.subject)}<span style="color:red">{$errors.subject}</span>{/if}
                </p>   
                <p>
                    <label for="message">Votre message</label><br />
                    <textarea name="contact[message]" id="message">{$values.message}</textarea>
                    {if isset($errors.message)}<span style="color:red">{$errors.message}</span>{/if}
                </p>   
                <p>
                    <button type="submit">Soumettre</button>
                </p>
            </form>
        </pre>
                
        <h2>Widget</h2>
        <p>
            Comme tous les contrôleurs, vous pouvez appeler le formulaire que l'on viens de créer dans un gabarit, 
            par exemple :
        </p>
        <pre class="brush: xml">
            &lt;!DOCTYPE html>
                &lt;head>
                    &lt;meta charset="utf-8">
                &lt;/head>    
                &lt;body>
                    &lt;h1>Formulaire de contact&lt;/h1>
                    &lt;p>Veuillez compléter le formulaire ci-dessous pour nous contacter&lt/p>
                    &lt;div id="contact_form">
                        {widget module="form" action="index"}
                    &lt;/div>
                &lt;/body>
            &lt;/html>
        </pre>
        
        
    </body>            
</html>